package com.alex.space.commons.jvm;

/**
 * @author Alex
 *         Created by Alex on 2017/12/27.
 *         <p>
 *         MaxTenuringThreshold研究
 *         MaxTenuringThreshold这个参数用于控制对象能经历多少次Minor GC才晋升到旧生代，默认值是15
 *         那是不是意味着对象要经历15次minor gc才晋升到旧生代呢
 */
public class GCTenuringThreshold {

    /**
     * 1. run with -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:+PrintTenuringDistribution
     * 2. run with -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:SurvivorRatio=1 -XX:MaxTenuringThreshold=3 -XX:+PrintGCDetails -XX:+PrintTenuringDistribution
     * <p>
     * -XX:+PrintTenuringDistribution 跟踪每次minor GC后新的存活周期的阈值
     * <p>
     * view jstat -gcutil [pid] 1000 10
     */
    public static void main(String[] args) throws Exception {
        // Case 1
//        GCMemoryObject1 object1 = new GCMemoryObject1(2);
//        GCMemoryObject1 object2 = new GCMemoryObject1(8);
//        GCMemoryObject1 object3 = new GCMemoryObject1(8);
//        GCMemoryObject1 object4 = new GCMemoryObject1(8);
//        object2 = null;
//        object3 = null;
//        GCMemoryObject1 object5 = new GCMemoryObject1(8);
//        Thread.sleep(4000);
//
//        object2 = new GCMemoryObject1(8);
//        object3 = new GCMemoryObject1(8);
//        object2 = null;
//        object3 = null;
//        object5 = null;
//        GCMemoryObject1 object6 = new GCMemoryObject1(8);
//        Thread.sleep(5000);
//
//        GCMemoryObject1 object7 = new GCMemoryObject1(8);
//        GCMemoryObject1 object8 = new GCMemoryObject1(8);
//        GCMemoryObject1 object9 = new GCMemoryObject1(8);
//        GCMemoryObject1 object10 = new GCMemoryObject1(8);
//        object6 = null;
//        Thread.sleep(5000);

        //Case 2
        GCMemoryObject2 object1 = new GCMemoryObject2(2f);
        GCMemoryObject2 object2 = new GCMemoryObject2(0.1f);

        Thread.sleep(4000);
        object1 = null;
        GCMemoryObject2 object3 = new GCMemoryObject2(2f);
        GCMemoryObject2 object4 = new GCMemoryObject2(0.1f);

        Thread.sleep(4000);
        object3 = null;
        GCMemoryObject2 object5 = new GCMemoryObject2(2f);
        GCMemoryObject2 object6 = new GCMemoryObject2(0.3f);

        Thread.sleep(4000);
        object5 = null;
        GCMemoryObject2 object7 = new GCMemoryObject2(2f);
        GCMemoryObject2 object8 = new GCMemoryObject2(0.3f);

        Thread.sleep(4000);
        object7 = null;
        GCMemoryObject2 object9 = new GCMemoryObject2(2f);
        GCMemoryObject2 object10 = new GCMemoryObject2(0.3f);

        System.out.println("ok");
    }

}

class GCMemoryObject1 {
    private byte[] bytes = null;

    public GCMemoryObject1(int multi) {
        bytes = new byte[1024 * 256 * multi];
    }
}

class GCMemoryObject2 {
    private byte[] bytes = null;

    public GCMemoryObject2(float multi) {
        bytes = new byte[(int) ((int) 1024 * 1024 * multi)];
    }
}